package com.Apo1o.security;

import com.Apo1o.exception.BusinessException;
import com.Apo1o.exception.CommonErrorCode;
import com.Apo1o.utils.JwtUtils;
import com.Apo1o.vo.TokenVo;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class TokenAuthFilter extends BasicAuthenticationFilter {

    private final Map<Integer, String> roleMap = new ConcurrentHashMap<>(3);

    public TokenAuthFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
        roleMap.put(1, "Ⅱ型糖尿病患者");
        roleMap.put(2, "医生");
        roleMap.put(3, "超级管理员");
    }

    /**
     * 处理过滤逻辑，用于认证通过JWT Token的用户请求。
     *
     * @param request  HttpServletRequest对象，代表客户端的HTTP请求
     * @param response HttpServletResponse对象，用于向客户端发送HTTP响应
     * @param chain    FilterChain对象，用于将请求传递给下一个过滤器或目标资源
     * @throws IOException 如果发生I/O错误
     * @throws ServletException 如果发生Servlet相关错误
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 通过JWT Token获取用户信息
        TokenVo userInfo = JwtUtils.getUserInfoByToken(request);
        // 如果无法获取用户信息，则抛出未授权异常
        if (userInfo == null) {
            throw new BusinessException(CommonErrorCode.UNAUTHORIZED);
        }
        // 初始化用户角色列表
        List<SimpleGrantedAuthority> roles = new ArrayList<>();
        // 根据用户角色ID，配置角色权限
        roles.add(new SimpleGrantedAuthority(roleMap.get(userInfo.getRoleId())));
        // 创建认证令牌，用于设置用户认证信息
        UsernamePasswordAuthenticationToken userAuthorization = new UsernamePasswordAuthenticationToken(userInfo.getUsername(), request.getHeader("authorization"), roles);
        // 设置当前线程的安全上下文认证信息
        SecurityContextHolder.getContext().setAuthentication(userAuthorization);
        // 继续处理请求链
        chain.doFilter(request, response);
    }

}
